package com.example.caoh.common.util;

import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;

/**
 * @author wuxi
 */
public class ElsQuery {

	private ElsBool bool = new ElsBool();;

	private JSONObject query = new JSONObject();
	private JSONObject sort;
	private JSONArray sorts;
	
	private JSONObject aggs;
	
	private JSONObject filters;
	
	private Set<String> fields;
	private Integer start = 0;
	private Integer size = 10;

	public ElsQuery(ElsIndex index) {
		this.index = index;
	}

	private ElsIndex index;

	public ElsIndex getIndex() {
		return index;
	}
	

	public JSONObject getAggs() {
		return aggs;
	}


	public void setAggs(JSONObject aggs) {
		this.aggs = aggs;
	}


	public void setIndex(ElsIndex index) {
		this.index = index;
	}

	public Integer getStart() {
		return start;
	}

	public void setStart(Integer start) {
		this.start = start;
	}

	public Integer getSize() {
		return size;
	}

	public void setSize(Integer size) {
		this.size = size;
	}

	public ElsBool getBool() {
		return bool;
	}

	public void setBool(ElsBool bool) {
		this.bool = bool;
	}

	/**
	 * 添加must查询条件
	 * 
	 * @param key
	 * @param value
	 */
	public void addLikeQuery(String key, String value) {
		if (Strings.isNullOrEmpty(value))
			return;
		addQuery(key, String.format("*%s*", value), ElsMethod.Must, ElsOp.Wildcard);
	}
	
	public void addQuery(String key, String value) {
		if (Strings.isNullOrEmpty(value))
			return;
		addQuery(key, value, ElsMethod.Must, ElsOp.Term);
	}
	public void addQueryNot(String key, String value) {
        if (Strings.isNullOrEmpty(value))
            return;
        addQuery(key, value, ElsMethod.MustNot, ElsOp.Term);
    }
	
	public void addQuery(String key, Collection<String> cole) {
		if (cole==null||cole.size()==0)
			return;
		addQuery(key, cole, ElsMethod.Must, ElsOp.Terms);
	}

	public void addQueryNot(String key, Collection<String> cole) {
		if (cole==null||cole.size()==0)
			return;
		addQuery(key, cole, ElsMethod.MustNot, ElsOp.Terms);
	}
	
	public void addQueryNot(String key, String value,ElsOp option){
        if (Strings.isNullOrEmpty(value))
            return;
        addQuery(key, value, ElsMethod.MustNot, option);
    }
	
	public void addQuery(String value) {
		if (Strings.isNullOrEmpty(value))
			return;
		JSONObject obj = new JSONObject();
		obj.put("default_field", "_all");
		obj.put("query", value);
		bool.add(ElsMethod.Must, ElsOp.QueryString, obj);
	}

	public void addQuery(String key, String value, ElsMethod method, ElsOp op) {
		JSONObject obj = new JSONObject();
		obj.put(key, value);
		bool.add(method, op, obj);
	}

	public void addQuery(String key, Collection<String> cole, ElsMethod method, ElsOp op) {
		JSONObject obj = new JSONObject();
		obj.put(key, cole);
		bool.add(method, op, obj);
	}
	
	public void addFilters(String key,String value,ElsOp option){
		if(null == filters)
			filters = new JSONObject();
		JSONObject obj = new JSONObject();
		switch (option) {
		case Exists:
			obj.put("field", key);
			filters.put(option.toString(), obj);
			break;

		default:
			break;
		}
	}
	/**
	 * 批量添加must查询条件
	 * 
	 * @param map
	 */
	public void addQuery(Map<String, Object> map) {
		for (Entry<String, Object> entry : map.entrySet()) {
			addQuery(entry.getKey(), entry.getValue().toString(), ElsMethod.Must, ElsOp.Term);
		}
	}

	public void addQuery(ElsBool bool, ElsMethod method) {
		this.bool.add(bool, method);
	}

	/**
	 * 添加范围查询
	 * 
	 * @param key
	 * @param value
	 * @param range
	 */
	public void addRange(String key, Object value, ElsRange range) {
		bool.addRange(key, value, range, ElsMethod.Must);
	}

	public void setFields(String... fields) {
		if (null == fields)
			this.fields = new HashSet<String>();
		else
			this.fields.clear();
		for (String filed : fields) {
			this.fields.add(filed);
		}
	}

	public void addFields(String field) {
		if (null == fields)
			this.fields = new HashSet<String>();
		this.fields.add(field);
	}

	public void addSort(String key, ElsOrder order) {
		if (null == sort)
			sort = new JSONObject();
		JSONObject obj = new JSONObject();
		obj.put("order", order.toString());
		sort.put(key, obj);
	}
	
	public void addSorts(JSONArray array) {
		if (null == sorts)
			sorts = new JSONArray();
		sorts = array;
	}

	public void sumAggs(String [] fileds) {
		JSONObject total = new JSONObject();
		for (int i = 0; i < fileds.length; i++) {
			JSONObject sum = new JSONObject();
			JSONObject field = new JSONObject();
			field.put("field", fileds[i]);
			sum.put("sum", field);
			total.put("sum_"+fileds[i], sum);
		}
		this.setAggs(total);
	}
	
	public String toString() {
		JSONObject obj = new JSONObject();
		obj.put("from", start);
		obj.put("size", size);
		query.put("bool", bool);
		obj.put("query", query);
		if (null != sorts)
			obj.put("sort", JSONArray.toJSON(sorts));
		if (null != sort)
			obj.put("sort", JSONObject.toJSON(sort));
		if (null != fields) {
			obj.put("_source", fields);
		}
		if (null != filters){
			obj.put("filter", filters);
		}
		if(null!=aggs){
			obj.put("aggs", aggs);
		}
		return obj.toString();
	}

}
